# -*- coding: utf-8 -*-
#    Copyright 2005 Spike^ekipS <spikeekips@gmail.com>
#
#       This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
from django.core.extensions import render_to_response
import simplejson, xmlrpclib, sqlobject, urllib

import model, http
from model import channel_entry
from model.channel import Channel as model_channel
from model.channel_user import ChannelUser as model_channel_user
from model.category_user import CategoryUser as model_category_user
from util import pager
from util import datetime__
import nokcene.result
import nokcene.xmlquery_new
import func
import config

def __serializeChannel (obj_channel) :
	__keys_channel = { \
		"id"           : None, \
		"href"         : None, \
		"language"     : None, \
		"link"         : None, \
		"subtitle"     : None, \
		"title"        : None, \
		"version"      : None, \
		"encoding"     : None, \
	}
	__keys_status = { \
		"title"        : "title_status", \
		"status"       : None, \
		"timeAdded"    : None, \
		"timeUpdated"  : None, \
	}

	__e = dict()
	for i, j in __keys_channel.items() :
		if j :
			__k = j
		else :
			__k = i
		__e.update({__k : unicode(getattr(obj_channel, i)), })

	for i, j in __keys_status.items() :
		if j :
			__k = j
		else :
			__k = i

		__e.update({__k : unicode(getattr(obj_channel.status, i)), })

	return __e

def index (request) :
	__user = request.session.get("user", False)
	if not __user :
		return HttpResponseRedirect("/frontpage/login")

	return render_to_response( \
		"channel/list_channel", \
	)

def __get_channel_data (id_channel) :
	return model_channel.get(id_channel)

def get_channel_info_box (request) :
	__argument = request.POST.copy()
	if not __argument.has_key("id_channel") : return http.exitWithStatus(404)

	__o = __get_channel_data(int(__argument["id_channel"]))
	return render_to_response( \
		"channel/info_channel_box.partial", \
		{
			"channel" : __o, \
		}
	)

def get_channel_data (request) :
	__argument = request.POST.copy()
	if not __argument.has_key("id_channel") : return http.exitWithStatus(404)

	__o = __get_channel_data(int(__argument["id_channel"]))
	return HttpResponse(simplejson.dumps(__serializeChannel(__o)))

def getChannelList (request) :
	__user = request.session.get("user")
	__id_category = request.POST.copy().get("id_category", None)

	if not __id_category :
		__clause_where = (model_channel_user.q.userID == __user.id)
	else :
		__clause_where = sqlobject.AND( \
				model_channel_user.q.userID == __user.id, \
				model_channel_user.q.categoryID == __id_category \
			)

	__o = list(model_channel_user.select(__clause_where))

	# get the category list.
	__category_list = list(model_category_user.select( \
		(model_category_user.q.userID == __user.id) \
	))

	#__o = list(channel.Channel.select())
	return render_to_response( \
		"channel/list_channel.partial", \
		{
			"list_channel" : __o, \
			"list_category" : __category_list, \
		}
	)

def getChannelEntryList (request) :
	__argument = request.POST.copy()
	if not __argument.has_key("id_channel") : return http.exitWithStatus(404)

	try :
		__channel_entry = channel_entry.get_entry(int(__argument["id_channel"]))
	except Exception, e :
		return http.exitWithStatus(500)

	# paging.
	__limit = 15
	__page = 0
	if __argument.has_key("p") : __page = __argument["p"]

	#__o = list(__channel_entry.select(orderBy=__channel_entry.q.id, reversed=True))

	__obj_pager = channel_entry.PagingChannelEntry(__channel_entry)
	__kwargs = { \
		"limit" : __limit, \
		"offset" : (__limit * __page), \
	}
	__pager = pager.Default(__obj_pager, __kwargs, __limit)
	__o = __pager.get_page(__page)

	return render_to_response( \
		"channel/list_channel_entry.partial", \
		{
			"id_channel" : __argument["id_channel"], \
			"list_channel_entry" : __o, \
			"pager" : __pager, \
		}
	)

def get_channel_entry_info (request) :
	__argument = request.POST.copy()
	if not __argument.has_key("id_channel") : return http.exitWithStatus(404)
	if not __argument.has_key("id_entry") : return http.exitWithStatus(404)

	try :
		__channel_entry = channel_entry.get_entry(int(__argument["id_channel"]))
	except Exception, e :
		return http.exitWithStatus(500)

	__o = __channel_entry.get(__argument["id_entry"])

	return render_to_response( \
		"channel/info_channel_entry.partial", \
		{
			"channel_entry" : __o, \
		}
	)

def getRSSUrlCandidate () :
	__argument = request.POST.copy()
	if not __argument.has_key("href") : return http.exitWithStatus(404)

	__href = __argument["href"]

def addChannel (request) :
	__user = request.session.get("user", False)
	if not __user :
		return http.exitWithStatus(500)

	__argument = request.POST.copy()
	if not __argument.has_key("hrefs") : return http.exitWithStatus(404)

	__list_href = __argument.getlist("hrefs")
	if len(__list_href) < 1 :
		return http.exitWithStatus(404)

	__server_add = xmlrpclib.Server("http://localhost:%d" % config.zzim_add_port)
	__id_channels = dict()
	for i in __list_href :
		__id_channels[i] = __server_add.addChannel(i)

	# add as category.
	__category_current = None
	for __href, __id_channel in __id_channels.items() :
		__kwargs_channel_user = { \
			"userID" : __user.id, \
			"channelID" : __id_channel, \
			"categoryID" : 0, \
			"timeAdded" : datetime__.now(), \
		}
		model_channel_user(**__kwargs_channel_user)

	return http.exitWithStatus(200)

def search (request) :
	__argument = request.POST.copy()
	if not __argument.has_key("input_search") : return http.exitWithStatus(404)

	__s = __argument["input_search"]
	__offset = int(__argument.get("offset", 0))

	# handle search string
	#__s = ["%s~" % i for i in func.split_with_field(__s)]
	__s = ["%s" % i for i in func.split_with_field(__s)]
	__s_or = " OR ".join(__s)
	__s_and = " OR ".join(__s)

	return_fields=(
		"title",
		"__uid__",
		"link__",
		"summary",
		"timeUpdated",
		"author",
	)
	search_fields=( \
		(
			"AND",
			{
				"id" : "document_type",
				"type" : "keyword",
				"value": "channel_entry",
				"usage" : "",
				"condition" : "AND",
			},
			(
				"OR",
				{
					"id" : "title",
					"type" : "",
					"value": "(%s)^4" % __s_and,
					"usage" : "",
				},
				{
					"id" : "summary",
					"type" : "",
					"value": "(%s)^4" % __s_and,
					"usage" : "",
				},
				{
					"id" : "title",
					"type" : "",
					"value": "(%s)" % __s_or,
					"usage" : "",
				},
				{
					"id" : "summary",
					"type" : "",
					"value": "(%s)" % __s_or,
					"usage" : "",
				},
			),
		),
	)
	search_options = { \
		"sort-on" : "uid",
		"sort-order" : "reverse",
		"start" : __offset,
		"size" : 15,
		"operator" : "OR",
	}

	"""
	__xml = nokcene.result.generate_xml_query( \
		return_fields=return_fields, \
		search_fields=search_fields, \
		search_options=search_options \
	)
	"""
	__xml = nokcene.xmlquery_new.args_to_xml( \
		return_fields=return_fields, \
		search_fields=search_fields, \
		search_options=search_options \
	)

	(__result, __num, ) = nokcene.result.get_result(__xml)

	# reform result
	__list_result = list()
	__pool_channel = dict()
	for i in __result :
		# get channel and channel_entry info
		__uid = i.get("__uid__", None)
		if not __uid :
			continue
		else :
			try :
				(__id_channel, __id_channel_entry, ) = \
					[int(j) for j in __uid.split(".")]
			except Exception, e :
				print e
				continue
			else :
				# get channel
				if __pool_channel.has_key(__id_channel) :
					__channel = __pool_channel[__id_channel][0]
					__entry = __pool_channel[__id_channel][1]
				else :
					__channel = model_channel.get(__id_channel)
					if not __channel :
						continue
					else :
						__entry = channel_entry.get_entry(__id_channel)
						__pool_channel[__id_channel] = (__channel, __entry, )

				# get channel_entry
				__entry = __entry.get(__id_channel_entry)

		__template_result_one = { \
			"title" : i.get("title", ""), \
			"__uid__" : i.get("__uid__", ""), \
			"link__" : i.get("link__", ""), \
			"summary" : i.get("summary", ""), \
			"timeUpdated" : i.get("timeUpdated", ""), \
			"author" : i.get("author", ""), \
			"channel" : __channel, \
			"entry" : __entry, \
		}
		__list_result.append(__template_result_one)

	if (__offset + 15) > __num :
		__offset_next = None
	else :
		__offset_next = __offset + 15

	if (__offset - 15) < 0 :
		__offset_prev = None
	else :
		__offset_prev = __offset - 15

	return render_to_response( \
		"channel/search_result.partial", \
		{
			"result" : __list_result, \
			"num" : __num, \
			"search_string" : urllib.quote(__argument["input_search"]), \
			"offset_next" : __offset_next, \
			"offset_prev" : __offset_prev, \
		}
	)

def saveCategory (request) :
	__user = request.session.get("user", False)
	if not __user :
		return http.exitWithStatus(500)

	__argument = request.POST.copy()
	if not __argument.has_key("name_category") : return http.exitWithStatus(404)

	# save category in CategoryUser
	__kwargs = { \
		"userID"	: __user.id, \
		"name"	: __argument["name_category"].strip(), \
	}
	__category = model_category_user(**__kwargs)
	if not __category :
		return http.exitWithStatus(404)

	return HttpResponse(simplejson.dumps({"id" : __category.id, }))

	#return http.exitWithStatus(200)

def changeCategory (request) :
	__user = request.session.get("user", False)
	if not __user :
		return http.exitWithStatus(500)

	__argument = request.POST.copy()
	if not __argument.has_key("id_category") : return http.exitWithStatus(404)
	if not __argument.has_key("target_category") : return http.exitWithStatus(404)
	__id_channel = __argument["id_category"]
	__target_category = int(__argument["target_category"])

	try :
		__channel = list(model_channel_user.select( \
			sqlobject.AND( \
				model_channel_user.q.channelID == __id_channel, \
				model_channel_user.q.userID == __user.id \
			)
		))
	except Exception, e :
		print e
		return http.exitWithStatus(404)
	else :
		print __channel
		__channel = __channel[0]
		if __channel.categoryID == __target_category :
			return http.exitWithStatus(405) # same category.
		else :
			__channel.categoryID = __target_category

			return http.exitWithStatus(200) # same category.


__author__ =  "Spike^ekipS <spikeekips@gmail.com>"
__version__=  "0.1"
__nonsense__ = ""

__file__ = "views.py"


